package com.emiage.ddutils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.ExifInterface;
import android.net.Uri;
import android.util.Base64;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

/**
 * Created by LiJZ on 2016/7/21.
 */
public class BitmapUtils {
	private static final String TAG = BitmapUtils.class.getSimpleName();

	/**
	 * convert Bitmap to byte array
	 */
	public static byte[] bitmapToByte(Bitmap b) {
		ByteArrayOutputStream o = new ByteArrayOutputStream();
		b.compress(Bitmap.CompressFormat.PNG, 100, o);
		return o.toByteArray();
	}

	/**
	 * convert byte array to Bitmap
	 */
	public static Bitmap byteToBitmap(byte[] b) {
		return (b == null || b.length == 0) ? null : BitmapFactory.decodeByteArray(b, 0, b.length);
	}

	/**
	 * 把bitmap转换成Base64编码String
	 */
//	public static String bitmapToString(Bitmap bitmap) {
//		return Base64.encodeToString(bitmapToByte(bitmap), Base64.DEFAULT);
//	}
	public static String bitmapToString(Bitmap bitmap) {
		String string = null;

		if (bitmap != null)
			string = bitmapToString(bitmap, 100);

		return string;
	}

	/**
	 * 将Bitmap转换成字符串
	 *
	 * @param bitmap
	 * @return String
	 */
	public static String bitmapToString(Bitmap bitmap, int quality) {
		String string = null;

		if (bitmap != null) {
			ByteArrayOutputStream bStream = new ByteArrayOutputStream();
			bitmap.compress(Bitmap.CompressFormat.JPEG, quality, bStream);
			byte[] bytes = bStream.toByteArray();

			string = Base64.encodeToString(bytes, Base64.DEFAULT);
		}

		return string;
	}

	/**
	 * convert Drawable to Bitmap
	 */
	public static Bitmap drawableToBitmap(Drawable drawable) {
		return drawable == null ? null : ((BitmapDrawable) drawable).getBitmap();
	}

	/**
	 * convert Bitmap to Drawable
	 */
	public static Drawable bitmapToDrawable(Bitmap bitmap) {
		return bitmap == null ? null : new BitmapDrawable(bitmap);
	}

	/**
	 * 获取bitmap尺寸缩放解决OOM问题
	 *
	 * @param filePath
	 * @param reqWidth
	 * @param reqHeight
	 * @return
	 */
	public static Bitmap convertBitmap(String filePath, int reqWidth, int reqHeight) {
		File picFile = FileUtils.createFile(filePath);
		if (!picFile.exists()) {
			return null;
		} //文件不存在

		Bitmap bitmap = null;
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true; // 只读取图片宽高
		BitmapFactory.decodeFile(filePath, options);
		options.inJustDecodeBounds = false; //读取图片

		int inSize = (int) inSampleSize(options, reqWidth, reqHeight, false); //得到图片的压缩比例
		options.inSampleSize = inSize;

		try {
			bitmap = BitmapFactory.decodeFile(filePath, options);
			if (bitmap != null) {
				//旋转角度
				Matrix matrix = rotateBitmap(filePath, bitmap);
				//是否压缩到指定的大小
				boolean isScale = false;
				//横
				if (options.outWidth > options.outHeight) {
					/**
					 * 宽高都大于指定宽高
					 * 对于横向的图片，宽的值大，就要和指定的高比较（因为现在规定的是720*960，竖向的）
					 */
					if (options.outHeight > reqWidth && options.outWidth > reqHeight)
						isScale = true;
				} else {
					/**
					 * 宽高都大于指定宽高
					 * 对于竖向的图片，高的值大，就要和指定的高比较（因为现在规定的是720*960，竖向的）
					 */
					if (options.outHeight > reqHeight && options.outWidth > reqWidth)
						isScale = true;
				}

				//把图片压缩到指定宽高
				if (isScale) {
					float fScale = inSampleSize(options, reqWidth, reqHeight, true);
					matrix.postScale(fScale, fScale);
				}

				Bitmap rotateBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
						bitmap.getHeight(), matrix, true);

				if (rotateBitmap != null)
					bitmap = rotateBitmap;
			}
		} catch (Exception e) {
			e.printStackTrace();
		} catch (OutOfMemoryError e) {
			e.printStackTrace();
		}

		return bitmap;
	}

	/**
	 * 根据希望宽度进行bitmap尺寸缩放
	 *
	 * @param filePath 源图片路径
	 * @param reqWidth 希望缩放宽度
	 * @param rotate   旋转角度
	 * @return 返回压缩图片，或null
	 */
	public static Bitmap resizeBitmap(String filePath, int reqWidth, int rotate) {
		File nSrcFile = FileUtils.createFile(filePath);
		if (!nSrcFile.exists()) {
			return null;
		} //文件不存在

		Bitmap nBitmap = null;
		BitmapFactory.Options nOptions = new BitmapFactory.Options();
		nOptions.inJustDecodeBounds = true; // true不会分配空间，就可以拿到原始图片的宽高
		BitmapFactory.decodeFile(filePath, nOptions);
		nOptions.inJustDecodeBounds = false; //读取图片
		if (rotate == 90 || rotate == 270) //得到图片的压缩比例
			nOptions.inSampleSize = nOptions.outHeight > reqWidth ? nOptions.outHeight / reqWidth : 1;
		else
			nOptions.inSampleSize = nOptions.outWidth > reqWidth ? nOptions.outWidth / reqWidth : 1;
		try {
			nBitmap = BitmapFactory.decodeFile(filePath, nOptions);
			if (nBitmap != null) {
				Matrix nMatrix = rotateBitmap(filePath, nBitmap); //旋转角度
				int nSrcWidth = nOptions.outWidth;
				if (rotate == 90 || rotate == 270)
					nSrcWidth = nOptions.outHeight;
				boolean nIsScale = reqWidth > nSrcWidth ? false : true; //是否压缩到指定的大小
				if (nIsScale) { //把图片压缩到指定宽度
					float nScale = getZoomValue(nSrcWidth, reqWidth);
					nMatrix.postScale(nScale, nScale);
				}
				Bitmap nRotateBitmap = Bitmap.createBitmap(nBitmap, 0, 0, nBitmap.getWidth(), nBitmap.getHeight(), nMatrix, true);
				if (nRotateBitmap != null)
					nBitmap = nRotateBitmap;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return nBitmap;
	}

	/**
	 * 根据希望宽度，得到缩放比例
	 *
	 * @param srcWidth 源图片的宽
	 * @param reqWidth 希望最大宽度
	 * @return 缩放比例
	 */
	public static float getZoomValue(int srcWidth, int reqWidth) {
		if (srcWidth < reqWidth) {
			return 1f;
		} else {
			return (float) reqWidth / srcWidth;
		}
	}


	public static Matrix rotateBitmap(String filePath, Bitmap bitmap) {
		int rotate = getPictureDegree(filePath);

		Matrix matrix = new Matrix();

		if (rotate != 0 && bitmap != null) {
			matrix.setRotate(rotate);
		}

		return matrix;
	}

	/**
	 * 得到图片的旋转角度
	 *
	 * @param filePath 文件路径
	 * @return Integer 旋转角度
	 */
	public static int getPictureDegree(String filePath) {
		// 获取图片的旋转角度
		int degree = 0;

		try {
			ExifInterface exifInterface = new ExifInterface(filePath);

			if (exifInterface != null) {

				int orientation = exifInterface.getAttributeInt(
						ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

				switch (orientation) {
					case ExifInterface.ORIENTATION_ROTATE_90:
						degree = 90;
						break;

					case ExifInterface.ORIENTATION_ROTATE_180:
						degree = 180;
						break;

					case ExifInterface.ORIENTATION_ROTATE_270:
						degree = 270;
						break;
				}
			}

		} catch (IOException e) {
			e.printStackTrace();
		}

		return degree;
	}

	/**
	 * 得到实际宽高和目标宽高的比率
	 *
	 * @param options
	 * @param reqWidth  目标宽度
	 * @param reqHeight 目标高度
	 * @param isScale   倍数还是压缩
	 * @return
	 */
	public static float inSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight, boolean isScale) {
		// 源图片的高度和宽度
		//竖
		int srcHeight = options.outHeight;
		int srcWidth = options.outWidth;
		//横
		if (options.outHeight < options.outWidth) {
			srcHeight = options.outWidth;
			srcWidth = options.outHeight;
		}

		float inSampleSize = 1f;

		float heightRatio = 1f;
		float widthRatio = 1f;

		if (isScale) {
			//目标宽高和实际宽高的比例， 要比例最小的
			if (srcHeight > reqHeight && srcWidth > reqWidth) {

				widthRatio = (float) reqWidth / srcWidth;
				heightRatio = (float) reqHeight / srcHeight;

				if ((float) srcHeight / srcWidth > 2.0) {//竖长条
					inSampleSize = widthRatio;
				} else if ((float) srcWidth / srcHeight > 2.0) {//横长条
					inSampleSize = heightRatio;
				} else {
					// 选择宽和高中最小的比率作为inSampleSize的值，这样可以保证最终图片的宽和高
					// 一定都会小于等于目标的宽和高
					inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
				}
			}

		} else {
			// 计算出实际宽高和目标宽高的比率，要最大的压缩比
			if (srcHeight > reqHeight && srcWidth > reqWidth) {
				// 计算出实际宽高和目标宽高的比率
				widthRatio = (float) srcWidth / reqWidth;
				heightRatio = (float) srcHeight / reqHeight;

				if ((float) srcHeight / srcWidth > 2.0) {//竖长条
					inSampleSize = widthRatio;
				} else if ((float) srcWidth / srcHeight > 2.0) {//横长条
					inSampleSize = heightRatio;
				} else {
					// 选择宽和高中最大的比率作为inSampleSize的值，这样可以保证最终图片的宽和高
					// 一定都会小于等于目标的宽和高
					inSampleSize = heightRatio > widthRatio ? heightRatio : widthRatio;
				}
			}
			// 计算出实际宽高和目标宽高的比率，要最大的压缩比
//			else if (height < reqHeight && width < reqWidth) {
//				// 计算出实际宽高和目标宽高的比率
//
//				widthRatio = (float) reqWidth / width;
//				heightRatio = (float) reqHeight / height;
//
//				// 选择宽和高中最大的比率作为inSampleSize的值，这样可以保证最终图片的宽和高
//				// 一定都会小于等于目标的宽和高
//				inSampleSize = heightRatio > widthRatio ? heightRatio
//						: widthRatio;
//			}
		}

		return inSampleSize;
	}

	public static Bitmap decodeUriAsBitmap(Context context, Uri uri) {
		Bitmap bitmap = null;
		try {
			bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri));
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return bitmap;
	}

	/**
	 * 翻转
	 *
	 * @param filePath
	 * @param bitmap
	 * @return
	 */
	public static Bitmap rotateBitmapByPath(String filePath, Bitmap bitmap) {
		if (bitmap != null) {
			Matrix matrix = rotateBitmap(filePath, bitmap);
			Bitmap rotateBitmap = Bitmap
					.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
							bitmap.getHeight(), matrix, true);
			if (rotateBitmap != null) {
				// @lxh fix OutOfMemoryError start
				if (bitmap != null) {
					bitmap.recycle();
					bitmap = null;
				}
				// @lxh fix OutOfMemoryError end
				bitmap = rotateBitmap;
			}
		}
		return bitmap;
	}

	/**
	 * 转换图片成圆形
	 *
	 * @param bitmap 传入Bitmap对象
	 * @return
	 */
	public static Bitmap toRoundBitmap(Bitmap bitmap) {
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();
		float roundPx;
		float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom;

		if (width <= height) {
			roundPx = width / 2;

			left = 0;
			top = 0;
			right = width;
			bottom = width;

			height = width;

			dst_left = 0;
			dst_top = 0;
			dst_right = width;
			dst_bottom = width;
		} else {
			roundPx = height / 2;

			float clip = (width - height) / 2;

			left = clip;
			right = width - clip;
			top = 0;
			bottom = height;
			width = height;

			dst_left = 0;
			dst_top = 0;
			dst_right = height;
			dst_bottom = height;
		}

		Bitmap output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
		Canvas canvas = new Canvas(output);

		final Paint paint = new Paint();
		final Rect src = new Rect((int) left, (int) top, (int) right, (int) bottom);
		final Rect dst = new Rect((int) dst_left, (int) dst_top, (int) dst_right, (int) dst_bottom);
		final RectF rectF = new RectF(dst);

		paint.setAntiAlias(true);// 设置画笔无锯齿

		canvas.drawARGB(0, 0, 0, 0); // 填充整个Canvas

		// 以下有两种方法画圆,drawRounRect和drawCircle
		canvas.drawRoundRect(rectF, roundPx, roundPx, paint);// 画圆角矩形，第一个参数为图形显示区域，第二个参数和第三个参数分别是水平圆角半径和垂直圆角半径。
		// canvas.drawCircle(roundPx, roundPx, roundPx, paint);

		paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));// 设置两张图片相交时的模式,参考http://trylovecatch.iteye.com/blog/1189452
		canvas.drawBitmap(bitmap, src, dst, paint); // 以Mode.SRC_IN模式合并bitmap和已经draw了的Circle

		return output;
	}

	/**
	 * 圆角图片
	 * 可以自己修改颜色
	 *
	 * @param bitmap
	 * @return
	 */
	public static Bitmap getRoundedCornerBitmap(Context context, Bitmap bitmap) {
		float roundPx = 12;

		return getRoundedCornerBitmap(context, bitmap, roundPx, roundPx);
	}

	/**
	 * 圆角图片
	 * 可以自己修改颜色
	 *
	 * @param bitmap
	 * @return
	 */
	public static Bitmap getRoundedCornerBitmap(Context context, Bitmap bitmap, float rx, float ry) {
		if (bitmap == null)
			return null;

		Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
				bitmap.getHeight(), Bitmap.Config.ARGB_8888);
		Canvas canvas = new Canvas(output);

		Paint paint = new Paint();
		Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
		RectF rectF = new RectF(rect);
		paint.setAntiAlias(true);
		canvas.drawARGB(0, 0, 0, 0);
		//可以自己修改颜色
		paint.setColor(Color.GRAY);

		canvas.drawRoundRect(rectF, rx, ry, paint);
		paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

		canvas.drawBitmap(bitmap, rect, rect, paint);

		return output;
	}


	/***
	 * 设置图片倒影
	 *
	 * @param originalBitmap
	 * @return
	 */
	private Bitmap createReflectedImage(Bitmap originalBitmap) {
		// 图片与倒影间隔距离
		final int reflectionGap = 4;

		// 图片的宽度
		int width = originalBitmap.getWidth();
		// 图片的高度
		int height = originalBitmap.getHeight();

		Matrix matrix = new Matrix();
		// 图片缩放，x轴变为原来的1倍，y轴为-1倍,实现图片的反转
		matrix.preScale(1, -1);
		// 创建反转后的图片Bitmap对象，图片高是原图的一半。
		Bitmap reflectionBitmap = Bitmap.createBitmap(originalBitmap, 0,
				height / 2, width, height / 2, matrix, false);
		// 创建标准的Bitmap对象，宽和原图一致，高是原图的1.5倍。
		Bitmap withReflectionBitmap = Bitmap.createBitmap(width, (height
				+ height / 2 + reflectionGap), Bitmap.Config.ARGB_8888);

		// 构造函数传入Bitmap对象，为了在图片上画图
		Canvas canvas = new Canvas(withReflectionBitmap);
		// 画原始图片
		canvas.drawBitmap(originalBitmap, 0, 0, null);

		// 画间隔矩形
		Paint defaultPaint = new Paint();
		canvas.drawRect(0, height, width, height + reflectionGap, defaultPaint);

		// 画倒影图片
		canvas.drawBitmap(reflectionBitmap, 0, height + reflectionGap, null);

		// 实现倒影效果
		Paint paint = new Paint();
		LinearGradient shader = new LinearGradient(0, originalBitmap.getHeight(),
				0, withReflectionBitmap.getHeight(), 0x70ffffff, 0x00ffffff,
				Shader.TileMode.MIRROR);
		paint.setShader(shader);
		paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));

		// 覆盖效果
		canvas.drawRect(0, height, width, withReflectionBitmap.getHeight(), paint);

		return withReflectionBitmap;
	}


}
